// ---------------------------------------------------------------------------------------------------------------------
// LOCAL_HISTORY_TABLE.h
// ---------------------------------------------------------------------------------------------------------------------
// Project:	Alpha Branch Predictor
// Authors:	Jabeer Ahmed, 
// 			Omar Mohsin, 
// 			Fadi Butti
// Course:	ECE - 586 (Winter 2013)
// Prof:	Mark Faust
// Portland State University
// ---------------------------------------------------------------------------------------------------------------------

#ifndef __LOCAL_HISTORY_TABLE_H__
#define __LOCAL_HISTORY_TABLE_H__

#include "types.h"
#include "shift_registers.h"
#include "counters.h"

#define DEFAULT_LOCAL_TABLE_SIZE 1024
#define DEFAULT_HISTORY_PATTERN_SIZE 10
#define LOCAL_TABLE_INDX(pc_address) pc_address & (DEFAULT_LOCAL_TABLE_SIZE - 1)

using namespace std;

class local_history_table {
	vector<shift_reg> table;
    uint table_length;
    uint pattern_width;
public:
	local_history_table():table_length(DEFAULT_LOCAL_TABLE_SIZE),pattern_width(DEFAULT_HISTORY_PATTERN_SIZE)
    {
		for (int i=0; i<table_length; i++)
            table.push_back(shift_reg(pattern_width));
    }
	local_history_table(uint length, uint width):table_length(length),pattern_width(width)
    {
		for (int i=0; i<table_length; i++)
            table.push_back(shift_reg(pattern_width));
	}
    inline uint indexFor(uint pc)
    {
        return pc & (table_length - 1);
    }
	shift_reg& operator[] (int pc){
		return table[indexFor(pc)];
	} 
};

class local_prediction_table {
	counter3 *table;
    uint size;
public:
	local_prediction_table(){
		table = new  counter3[DEFAULT_LOCAL_TABLE_SIZE];
	}
	local_prediction_table(int length):size(length){
		table = new  counter3[size];
	}
	~local_prediction_table(){
		delete table;
	}
    inline uint indexFor(uint pc)
    {
        return pc & (size - 1);
    }
	counter3& operator[] (int pc){
		return table[indexFor(pc)];
	} 
};


#endif 	// __LOCAL_HISTORY_TABLE_H__